import java.util.*;

public class BasicApplication {
    public static void main(String[] args) throws Exception {
        BasicApplication app = new BasicApplication();
        // app.testParse();
        // try {
        //     Set<String> set = new HashSet<>(app.testList());
        //     System.out.println(set.add(123 + ""));   //添加同样元素，返回false
        //     System.out.println(set);
        // } catch (Exception e) {
        //     System.out.println("Exception: " + e);
        // }
        // mapDemo();
        basicExceptionHandling();
        multipleExceptionHandling();
        customExceptionDemo();
        exceptionChainDemo();
        methodA();
        methodB();
    }

    public void testParse() {
        String name = "Java123";
        // 抛出异常java.lang.NumberFormatException
        int age = Integer.parseInt(name);
        System.out.println("Hello, " + name + " " + age);
    }

    public Set<String> testList() {
        return Set.of("Java", "Python", "C++", "123");
    }

    private static void mapDemo() {
        System.out.println("\n=== Map集合演示 ===");

        // HashMap：基于哈希表，无序，O(1)时间复杂度
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("Java", 95);
        hashMap.put("Python", 88);
        hashMap.put("Go", 92);
        System.out.println("HashMap: " + hashMap);

        // TreeMap：基于红黑树，按key排序，O(log n)时间复杂度
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("C++", 85);
        treeMap.put("Python", 88);
        treeMap.put("Java", 95);
        System.out.println("TreeMap: " + treeMap);  // 按key排序

        // LinkedHashMap：保持插入顺序的HashMap
        Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("第一门", 90);
        linkedHashMap.put("第二门", 85);
        linkedHashMap.put("第三门", 92);
        System.out.println("LinkedHashMap: " + linkedHashMap);

        // Hashtable：线程安全的HashMap，不允许null
        Map<String, String> hashtable = new Hashtable<>();
        hashtable.put("安全", "线程安全");
        // hashtable.put(null, "不允许");  // 会抛出异常
        System.out.println("Hashtable: " + hashtable);
    }

    /**
     * 基本异常处理演示
     */
    private static void basicExceptionHandling() {
        System.out.println("=== 基本异常处理 ===");

        try {
            int result = 10 / 0;  // 会抛出ArithmeticException
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("捕获到算术异常: " + e.getMessage());
            //e.printStackTrace();  // 打印异常堆栈
        }

        System.out.println("程序继续执行...\n");
    }

    /**
     * 多重异常处理演示
     */
    private static void multipleExceptionHandling() {
        System.out.println("=== 多重异常处理 ===");

        String[] array = {"1", "2", "abc", "4"};

        for (int i = 0; i <= array.length; i++) {
            try {
                int num = Integer.parseInt(array[i]);
                System.out.println("解析成功: " + num);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组越界: 索引 " + i + " 超出范围");
            } catch (NumberFormatException e) {
                System.out.println("数字格式错误: " + array[i] + " 不是有效数字");
            } catch (Exception e) {
                System.out.println("其他异常: " + e.getMessage());
            }
        }
        System.out.println();
    }

    /**
     * 自定义异常演示
     */
    private static void customExceptionDemo() {
        System.out.println("=== 自定义异常演示 ===");

        try {
            validateAge(-5);
        } catch (InvalidAgeException e) {
            System.out.println("捕获到自定义异常: " + e.getMessage());
            System.out.println("错误代码: " + e.getErrorCode());
        }
        System.out.println();
    }

    /**
     * 年龄验证方法
     */
    private static void validateAge(int age) throws InvalidAgeException {
        if (age < 0 || age > 150) {
            throw new InvalidAgeException("年龄必须在0-150之间", "AGE_001");
        }
        System.out.println("年龄验证通过: " + age);
    }

    /**
     * 异常链演示
     */
    private static void exceptionChainDemo() {
        System.out.println("=== 异常链演示 ===");

        try {
            methodA();
        } catch (Exception e) {  // 直接处理了所有异常，没有向外抛出异常，所以不需要声明throws
            System.out.println("最终捕获异常: " + e.getMessage());
            System.out.println("原始异常: " + e.getCause().getMessage());
        }
    }
    private static void methodA() throws Exception {
        try {
            methodB();
        } catch (RuntimeException e) {
            // 包装异常，保留原始异常信息
            // 需要throws Exception是因为它显式地throw new Exception，抛出了检查型异常(Exception)
            throw new Exception("methodA中发生错误", e);
        }
    }

    private static void methodB() {
        // 抛出的是RuntimeException（非检查型异常），不需要在方法签名中声明throws
        throw new RuntimeException("methodB中的原始错误");
    }
}

class InvalidAgeException extends Exception {
    private String errorCode;

    public InvalidAgeException(String message, String errorCode) {
        super(message);
        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }
}
